#include"reDoor.h"
#include "common_def.h"
#include "soc_osal.h"
#include "app_init.h"
#include "pinctrl.h"
#include "uart.h"
// #include "pm_clock.h"
#include "sle_low_latency.h"

#define SLE_GATEWAY_TASK_STACK_SIZE            0x1000
#include "sle_connection_manager.h"
#include "sle_ssap_client.h"
#include "sle_uart_client.h"

#include "lwip/nettool/misc.h"
#include "lwip/ip4_addr.h"
#include "lwip/netif.h"
#include "lwip/netifapi.h"
#include "lwip/sockets.h"
#include "wifi_connect.h"

#include <stdio.h>
#include <string.h>
#include "watchdog.h"
#include "i2c.h"
#include "osal_debug.h"
#include "cmsis_os2.h"

#include "ssd1306_fonts.h"
#include "ssd1306.h"
#include "gpio.h"

#include "chinese_fonts.h"
// #define CONFIG_WIFI_SSID            "11"                              // 要连接的WiFi 热点账号
// #define CONFIG_WIFI_PWD             "87654321"                        // 要连接的WiFi 热点密码
// #define CONFIG_SERVER_IP            "192.168.98.21" 
// #define CONFIG_SERVER_PORT          8080   

#define I2C_MASTER_ADDR                   0x0
#define I2C_SET_BAUDRATE                  400000
#define I2C_MASTER_PIN_MODE               2

#define I2C_TASK_STACK_SIZE               0x1000
#define I2C_TASK_DURATION_MS              500
#define I2C_TASK_PRIO                     (osPriority_t)(17)

bool shtStarFlag = false;
bool ledFlag = false;
int showFlag = 0;
char buff_out[100]={0};//总接收区
char humidity[5] = {0};//湿度
char temperature[5] = {0};//温度
char light[5]={0};//光照
char radar[5]={0};//雷达
char haiba[5]={0};//海拔
char weidu[15]={0};//纬度
char jdu[15]={0};//经度
// 旋转门算法状态实例
SwingingDoorState temp_state;
SwingingDoorState humi_state;
SwingingDoorState light_state;
SwingingDoorState radar_state;

// 实际显示的数值（字符串）
char humidity_display[5] = "0";
char temperature_display[5] = "0";
char light_display[5] = "0";
char radar_display[5] = "0";
// 在sock_fd 进行监听，在 new_fd 接收新的链接
int g_sock_fd;

// 服务器的地址信息
struct sockaddr_in g_send_addr;
socklen_t g_addr_length = sizeof(g_send_addr);


#define SLE_GATEWAY_TASK_PRIO                  28
#define SLE_GATEWAY_TASK_DURATION_MS           2000
#define SLE_GATEWAY_BAUDRATE                   115200
#define SLE_GATEWAY_TRANSFER_SIZE              256

static uint8_t g_app_uart_rx_buff[SLE_GATEWAY_TRANSFER_SIZE] = { 0 };

static uart_buffer_config_t g_app_uart_buffer_config = {
    .rx_buffer = g_app_uart_rx_buff,
    .rx_buffer_size = SLE_GATEWAY_TRANSFER_SIZE
};

static void uart_init_config(void)
{
    uart_attr_t attr = {
        .baud_rate = SLE_GATEWAY_BAUDRATE,
        .data_bits = UART_DATA_BIT_8,
        .stop_bits = UART_STOP_BIT_1,
        .parity = UART_PARITY_NONE
    };

    uart_pin_config_t pin_config = {
        .tx_pin = CONFIG_UART_TXD_PIN,
        .rx_pin = CONFIG_UART_RXD_PIN,
        .cts_pin = PIN_NONE,
        .rts_pin = PIN_NONE
    };
    uapi_uart_deinit(CONFIG_SLE_GATEWAY_BUS);
    uapi_uart_init(CONFIG_SLE_GATEWAY_BUS, &pin_config, &attr, NULL, &g_app_uart_buffer_config);

}


//回调
void sle_uart_notification_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data,
    errcode_t status)
{
    unused(client_id);
    unused(conn_id);
    unused(status);
    
    uapi_uart_write(CONFIG_SLE_GATEWAY_BUS, (uint8_t *)(data->data), data->data_len, 0);
    sendto(g_sock_fd, (uint8_t *)(data->data), data->data_len, 0, (struct sockaddr *)&g_send_addr, g_addr_length);

    memcpy(buff_out, data->data, data->data_len);  // 将接收到的数据拷贝到 buff_out
    buff_out[data->data_len] = '\0';         // 确保字符串以 null 结尾
    
//1,Hum:%s,Tem:%s,Lig:%s,Radar:%s进行拼接
// 1,Hum:%s,Tem:%s,Lig:%s,Radar:%s,GPS:%s,Ver:1
    // if (sscanf(buff_out, "1,Hum:%[^,],Tem:%[^,],Lig:%[^,],Radar:%[^,],GPS:%[^,],%[^,],%[^,]", humidity, temperature,light,radar,weidu,jdu,haiba) == 7) {
    
    // osal_printk(" 湿度: %s\r\n", humidity);
    // osal_printk(" 温度: %s\r\n", temperature);
    // osal_printk(" 光照: %s\r\n", light);
    // osal_printk(" 雷达: %s\r\n", radar);
    // osal_printk(" 纬度: %s\r\n", weidu);
    // osal_printk(" 经度: %s\r\n", jdu);
    // osal_printk(" 海拔: %s\r\n", haiba);
    // osal_printk("%s\r\n",CONFIG_STU_NAME);
    // osal_printk("%s\r\n",CONFIG_STU_NUM);
    // osal_printk("\r\n");
    // }
    // else{
    //     osal_printk("解析失败\r\n");
    //     osal_printk("\n sle 数据 : %s\r\n", data->data);
    // }

    if (sscanf(buff_out, "1,Hum:%[^,],Tem:%[^,],Lig:%[^,],Radar:%[^,],GPS:%[^,],%[^,],%[^,]",
            humidity, temperature, light, radar, weidu, jdu, haiba) == 7) 
    {
        // 转换为浮点数
        float temp_val = atof(temperature);
        float humi_val = atof(humidity);
        float light_val = atof(light);
        float radar_val = atof(radar);
        
        
        // 处理温度数据
        if (swinging_door_process(&temp_state, temp_val)) {
            snprintf(temperature_display, sizeof(temperature_display), "%.1f", temp_val);
            
        }
        
        // 处理湿度数据
        if (swinging_door_process(&humi_state, humi_val)) {
            snprintf(humidity_display, sizeof(humidity_display), "%.1f", humi_val);
            osal_printk("压缩节点，湿度：%s\r\n",humidity_display);
        }
        
        // 处理光照数据
        if (swinging_door_process(&light_state, light_val)) {
            snprintf(light_display, sizeof(light_display), "%.0f", light_val);
            osal_printk("压缩节点，光照：%s\r\n",light_display);
        }
        
        // 处理雷达数据
        if (swinging_door_process(&radar_state, radar_val)) {
            snprintf(radar_display, sizeof(radar_display), "%.0f", radar_val);
            osal_printk("压缩节点，雷达：%s\r\n",radar_display);
        }
        osal_printk(" 湿度: %s\r\n", humidity);
        osal_printk(" 温度: %s\r\n", temperature);
        osal_printk(" 光照: %s\r\n", light);
        osal_printk(" 雷达: %s\r\n", radar);
        osal_printk(" 纬度: %s\r\n", weidu);
        osal_printk(" 经度: %s\r\n", jdu);
        osal_printk(" 海拔: %s\r\n", haiba);
        osal_printk("\r\n");
        osal_printk("压缩中\r\n");
        osal_printk("%s\r\n",CONFIG_STU_NAME);
        osal_printk("%s\r\n",CONFIG_STU_NUM);
        osal_printk("\r\n");
    }
    else{
        osal_printk("解析失败\r\n");
        osal_printk("\n sle 数据 : %s\r\n", data->data);
    }
    osal_printk("B runing\r\n");
}

void sle_uart_indication_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data,
    errcode_t status)
{
    unused(client_id);
    unused(conn_id);
    unused(status);
    // osal_printk("\n sle uart recived data : %s\r\n", data->data);
    uapi_uart_write(CONFIG_SLE_GATEWAY_BUS, (uint8_t *)(data->data), data->data_len, 0);
}

static void sle_uart_client_read_int_handler(const void *buffer, uint16_t length, bool error)
{
    unused(error);
    ssapc_write_param_t *sle_uart_send_param = get_g_sle_uart_send_param();
    uint16_t g_sle_uart_conn_id = get_g_sle_uart_conn_id();
    sle_uart_send_param->data_len = length;
    sle_uart_send_param->data = (uint8_t *)buffer;
    ssapc_write_req(0, g_sle_uart_conn_id, sle_uart_send_param);


}

static void *sle_uart_client_task(const char *arg)
{
    unused(arg);
    char recvBuf[512];

    // 初始化（假设数据每2秒发送一次）
    swinging_door_init(&temp_state, 0.5f, 2.0f);  // 温度偏差0.5，间隔2秒
    swinging_door_init(&humi_state, 1.0f, 2.0f);   // 湿度偏差1.0
    swinging_door_init(&light_state, 10.0f, 2.0f); // 光照偏差10
    swinging_door_init(&radar_state, 1.0f, 2.0f);  // 雷达偏差1.0
    /* UART init config. */
    uart_init_config();
    osal_printk("B runing\r\n");
    /*  Wifi connect */
    char wifi_name[10] = {0};
    char wifi_paw[10] = {0};
    char messageLED[]="AcloseLED";

    // 初始化 WiFi 名称和密码
    snprintf((char *)wifi_name, 10, "%s", CONFIG_WIFI_SSID);
    snprintf((char *)wifi_paw, 10, "%s", CONFIG_WIFI_PWD);

    // 调用 WiFi 连接函数
    wifi_connect(wifi_name, wifi_paw);
    // wifi_connect(CONFIG_WIFI_SSID, CONFIG_WIFI_PWD);

    uapi_pin_set_mode(CONFIG_BLINKY_PIN, PIN_MODE_0);
    uapi_gpio_set_dir(CONFIG_BLINKY_PIN, GPIO_DIRECTION_OUTPUT);
    uapi_gpio_set_val(CONFIG_BLINKY_PIN, GPIO_LEVEL_LOW);

    /* create socket */
    printf("create socket start!\r\n");
    if ((g_sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        printf("create socket failed!\r\n");
        return 0;
    }
    g_send_addr.sin_family = AF_INET;
    g_send_addr.sin_port = htons(CONFIG_SERVER_PORT);
    g_send_addr.sin_addr.s_addr = inet_addr(CONFIG_SERVER_IP);
    g_addr_length = sizeof(g_send_addr);
    printf("create socket end!\r\n");

    uapi_uart_unregister_rx_callback(CONFIG_SLE_GATEWAY_BUS);
    errcode_t ret = uapi_uart_register_rx_callback(CONFIG_SLE_GATEWAY_BUS,
                                                   UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,
                                                   1, sle_uart_client_read_int_handler);
    sle_uart_client_init(sle_uart_notification_cb, sle_uart_indication_cb);
    
    if (ret != ERRCODE_SUCC) {
        osal_printk("Register uart callback fail.");
        return NULL;
    }
    while (1) {
        bzero(recvBuf, sizeof(recvBuf));
        // 接收服务端返回的字符串
        recvfrom(g_sock_fd, recvBuf, sizeof(recvBuf), 0, (struct sockaddr *)&g_send_addr, &g_addr_length);
        // printf("%s:%d=>%s\n", inet_ntoa(send_addr.sin_addr), ntohs(send_addr.sin_port), recvBuf);
        



        if(recvBuf[0]=='B'){
            if (recvBuf[1] == 'o') {
                ledFlag = true;
                osal_printk("打开LED\r\n");
            } else if (recvBuf[1] == 'c') {
                ledFlag = false;
                osal_printk("关闭LED\r\n");
            }
            else
                osal_printk("未能解析的命令\r\n");
        }else if(recvBuf[0]=='A'){
            ssapc_write_param_t *sle_uart_send_param = get_g_sle_uart_send_param();
            uint16_t g_sle_uart_conn_id = get_g_sle_uart_conn_id();
            sle_uart_send_param->data_len = strlen(recvBuf);
            sle_uart_send_param->data = (uint8_t *)recvBuf;
            ssapc_write_req(0, g_sle_uart_conn_id, sle_uart_send_param);
        }
    }


    return NULL;
}


static void sle_uart_entry(void)
{
    osal_task *task_handle = NULL;
    osal_kthread_lock();
    task_handle = osal_kthread_create((osal_kthread_handler)sle_uart_client_task, 0, "SLEUartDongleTask",
                                      SLE_GATEWAY_TASK_STACK_SIZE);
    if (task_handle != NULL) {
        osal_kthread_set_priority(task_handle, SLE_GATEWAY_TASK_PRIO);
    }
    osal_kthread_unlock();
}

static void app_i2c_init_pin(void)
{
    /* I2C pinmux. */
    uapi_pin_set_mode(CONFIG_I2C_SCL_MASTER_PIN, I2C_MASTER_PIN_MODE);
    uapi_pin_set_mode(CONFIG_I2C_SDA_MASTER_PIN, I2C_MASTER_PIN_MODE);       
    uapi_pin_set_pull(CONFIG_I2C_SCL_MASTER_PIN, PIN_PULL_TYPE_UP);
    uapi_pin_set_pull(CONFIG_I2C_SDA_MASTER_PIN, PIN_PULL_TYPE_UP);
}

static void *i2c_master_task(const char *arg)
{
    unused(arg);

    uint32_t baudrate = I2C_SET_BAUDRATE;
    uint8_t hscode = I2C_MASTER_ADDR;

    app_i2c_init_pin();
    uapi_i2c_master_init(CONFIG_I2C_MASTER_BUS_ID, baudrate, hscode);

  
    ssd1306_Init();
    ssd1306_Fill(Black);  // 清空屏幕，设置为黑色背景
    

    while (1) {
        osal_msleep(I2C_TASK_DURATION_MS);  
        if (showFlag==0) {  
            // 绘制左侧温湿度标签
            DrawChineseChar(0, 0, tem);     // 在(0,0)位置显示"温"字
            DrawChineseChar(16, 0, du);     // 在(16,0)位置显示"度"字
            DrawChineseChar(0, 16, hum);    // 在(0,16)位置显示"湿"字
            DrawChineseChar(16, 16, du);    // 在(16,16)位置显示"度"字
            DrawChineseChar(0, 32, lig);    // 在(0,32)位置显示"湿"字
            DrawChineseChar(16, 32, ht);    // 在(16,32)位置显示"度"字
            DrawChineseChar(0,48,ra);//雷
            DrawChineseChar(16,48,dar);//达
            // 显示温度
            ssd1306_SetCursor(50, 0);  
            ssd1306_DrawString(temperature, Font_7x10, White);
            
            // 显示湿度
            ssd1306_SetCursor(50, 16);
            ssd1306_DrawString(humidity, Font_7x10, White);
            //光照
            ssd1306_SetCursor(50, 32);
            ssd1306_DrawString(light, Font_7x10, White);
            //雷达
            ssd1306_SetCursor(50, 48);
            ssd1306_DrawString(radar, Font_7x10, White);
            // 绘制底部姓名
            DrawChineseChar(75, 48, tang);   
            DrawChineseChar(91, 48, ao);    
            DrawChineseChar(107, 48, yu); 
        }else if(showFlag==1){
            DrawChineseChar(0, 0, wei);     // 纬
            DrawChineseChar(16, 0, du);     // 度
            DrawChineseChar(0, 16, jin);    // 经
            DrawChineseChar(16, 16, du);    // 度
            DrawChineseChar(0, 32, hai);    // 海
            DrawChineseChar(16, 32, ba);    // 拔
            
            
            // 显示纬度
            ssd1306_SetCursor(50, 0);  
            ssd1306_DrawString(weidu, Font_7x10, White);
            // 显示经度
            ssd1306_SetCursor(50, 16);
            ssd1306_DrawString(jdu, Font_7x10, White);
            //显示海拔
            ssd1306_SetCursor(50, 32);
            ssd1306_DrawString(haiba, Font_7x10, White);
        }else if(showFlag==2) {  
            // 绘制左侧温湿度标签
            DrawChineseChar(0, 0, tem);  
            DrawChineseChar(16, 0, du);  
            DrawChineseChar(0, 16, hum); 
            DrawChineseChar(16, 16, du); 
            DrawChineseChar(0, 32, lig); 
            DrawChineseChar(16, 32, ht); 
            DrawChineseChar(0,48,ra);//雷
            DrawChineseChar(16,48,dar);//达
            // 显示温度
            ssd1306_SetCursor(50, 0);  
            ssd1306_DrawString(temperature_display, Font_7x10, White);
            
            // 显示湿度
            ssd1306_SetCursor(50, 16);
            ssd1306_DrawString(humidity_display, Font_7x10, White);
            //光照
            ssd1306_SetCursor(50, 32);
            ssd1306_DrawString(light_display, Font_7x10, White);
            //雷达
            ssd1306_SetCursor(50, 48);
            ssd1306_DrawString(radar_display, Font_7x10, White);


            ssd1306_SetCursor(75, 48);
            ssd1306_DrawString("forecast", Font_7x10, White);
        }
        else{
            ssd1306_Fill(Black);
        }
        

        if(ledFlag){
            uapi_gpio_toggle(CONFIG_BLINKY_PIN);
        }
        else{
            uapi_gpio_set_val(CONFIG_BLINKY_PIN, GPIO_LEVEL_LOW);
        }
        ssd1306_UpdateScreen();  
    }
    return NULL;
}

static void i2c_master_entry(void)
{
    osThreadAttr_t attr;

    attr.name = "I2cMasterTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = I2C_TASK_STACK_SIZE;
    attr.priority = I2C_TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)i2c_master_task, NULL, &attr) == NULL) {
        /* Create task fail. */
    }
}


#define DEBOUNCE_TIME_MS 50  // 防抖时间，单位为毫秒

static void gpio_callback_func(pin_t pin, uintptr_t param)
{
    UNUSED(pin);
    UNUSED(param);

    // 延迟一段时间后再次确认按钮状态
    osDelay(DEBOUNCE_TIME_MS);

    // 再次检查按钮状态
    if (uapi_gpio_get_val(CONFIG_BUTTON_PIN) == GPIO_LEVEL_LOW)  // 假设按钮按下为低电平
    {
            if(showFlag<2){
                showFlag++;
                ssd1306_Fill(Black);
            }
            else{
                showFlag=0;
                ssd1306_Fill(Black);
            }
            osal_printk("切换页面：%d\r\n",showFlag);
    }
}
static void button_entry(void)
{
    uapi_pin_set_mode(CONFIG_BUTTON_PIN, HAL_PIO_FUNC_GPIO);
    uapi_pin_set_pull(CONFIG_BUTTON_PIN, PIN_PULL_TYPE_UP);
    uapi_gpio_set_dir(CONFIG_BUTTON_PIN, GPIO_DIRECTION_INPUT);    
    uapi_gpio_register_isr_func(CONFIG_BUTTON_PIN, GPIO_INTERRUPT_DEDGE, gpio_callback_func);
}
app_run(sle_uart_entry);
app_run(i2c_master_entry);
app_run(button_entry);